home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2001 December / pcwk12201b.iso / Wersje pelne i specjalne / Winamp 2.77 i 3.0beta / wasabi-sdk_beta1.exe / studio / common / dispatch.h < prev    next >
C/C++ Source or Header  |  2001-10-08  |  29KB  |  609 lines

  1. /*
  2.  
  3.   Nullsoft WASABI Source File License
  4.  
  5.   Copyright 1999-2001 Nullsoft, Inc.
  6.  
  7.     This software is provided 'as-is', without any express or implied
  8.     warranty.  In no event will the authors be held liable for any damages
  9.     arising from the use of this software.
  10.  
  11.     Permission is granted to anyone to use this software for any purpose,
  12.     including commercial applications, and to alter it and redistribute it
  13.     freely, subject to the following restrictions:
  14.  
  15.     1. The origin of this software must not be misrepresented; you must not
  16.        claim that you wrote the original software. If you use this software
  17.        in a product, an acknowledgment in the product documentation would be
  18.        appreciated but is not required.
  19.     2. Altered source versions must be plainly marked as such, and must not be
  20.        misrepresented as being the original software.
  21.     3. This notice may not be removed or altered from any source distribution.
  22.  
  23.  
  24.   Brennan Underwood
  25.   brennan@nullsoft.com
  26.  
  27. */
  28.  
  29. #ifndef _DISPATCH_H
  30. #define _DISPATCH_H
  31.  
  32. #include "common.h"
  33.  
  34. class DispatchableCallback;
  35.  
  36. #pragma warning(disable: 4275)
  37. class NOVTABLE Dispatchable {
  38. public:
  39. //  // fake virtual destructor
  40. //  void destruct() { _voidcall(DESTRUCT); }
  41.  
  42.   // this is virtual so it is visible across modules
  43.   virtual int _dispatch(int msg, void *retval, void **params=NULL, int nparam=0)=0;
  44.  
  45. protected:
  46. //  // protected real destructor
  47. //  ~Dispatchable() {}
  48.   // helper templates to implement client-side methods
  49.   int _voidcall(int msg) {
  50.     return _dispatch(msg, NULL);
  51.   }
  52.  
  53.   template<class PARAM1>
  54.   int _voidcall(int msg, PARAM1 param1) {
  55.     void *params[1] = { ¶m1 };
  56.     return _dispatch(msg, NULL, params, 1);
  57.   }
  58.  
  59.   template<class PARAM1, class PARAM2>
  60.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2) {
  61.     void *params[2] = { ¶m1, ¶m2 };
  62.     return _dispatch(msg, NULL, params, 2);
  63.   }
  64.  
  65.   template<class PARAM1, class PARAM2, class PARAM3>
  66.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3) {
  67.     void *params[3] = { ¶m1, ¶m2, ¶m3 };
  68.     return _dispatch(msg, NULL, params, 3);
  69.   }
  70.  
  71.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4>
  72.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4) {
  73.     void *params[4] = { ¶m1, ¶m2, ¶m3, ¶m4 };
  74.     return _dispatch(msg, NULL, params, 4);
  75.   }
  76.  
  77.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
  78.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5) {
  79. //    void *params[4] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5 }; // mig found another bug
  80.     void *params[5] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5 };
  81.     return _dispatch(msg, NULL, params, 5);
  82.   }
  83.  
  84.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
  85.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6) {
  86. //    void *params[4] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 }; // mig found another bug
  87.     void *params[6] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 };
  88.     return _dispatch(msg, NULL, params, 6);
  89.   }
  90.  
  91.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
  92.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7) {
  93.     void *params[7] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 , ¶m7 };
  94.     return _dispatch(msg, NULL, params, 7);
  95.   }
  96.  
  97.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
  98.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8) {
  99.     void *params[8] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 , ¶m7 , ¶m8 };
  100.     return _dispatch(msg, NULL, params, 8);
  101.   }
  102.  
  103.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
  104.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9) {
  105.     void *params[9] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 , ¶m7 , ¶m8 , ¶m9 };
  106.     return _dispatch(msg, NULL, params, 9);
  107.   }
  108.  
  109.   template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
  110.   int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10) {
  111.     void *params[10] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 , ¶m7 , ¶m8 , ¶m9 , ¶m10 };
  112.     return _dispatch(msg, NULL, params, 10);
  113.   }
  114.  
  115.  
  116.   template<class RETURN_TYPE>
  117.   RETURN_TYPE _call(int msg, RETURN_TYPE defval) {
  118.     RETURN_TYPE retval;
  119.     if (_dispatch(msg, &retval)) return retval;
  120.     return defval;
  121.   }
  122.  
  123.   template<class RETURN_TYPE, class PARAM1>
  124.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1) {
  125.     void *params[1] = { ¶m1 };
  126.     RETURN_TYPE retval;
  127.     if (_dispatch(msg, &retval, params, 1)) return retval;
  128.     return defval;
  129.   }
  130.  
  131.   template<class RETURN_TYPE, class PARAM1, class PARAM2>
  132.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2) {
  133.     void *params[2] = { ¶m1, ¶m2 };
  134.     RETURN_TYPE retval;
  135.     if (_dispatch(msg, &retval, params, 2)) return retval;
  136.     return defval;
  137.   }
  138.  
  139.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3>
  140.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3) {
  141.     void *params[3] = { ¶m1, ¶m2, ¶m3 };
  142.     RETURN_TYPE retval;
  143.     if (_dispatch(msg, &retval, params, 3)) return retval;
  144.     return defval;
  145.   }
  146.  
  147.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4>
  148.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4) {
  149.     void *params[4] = { ¶m1, ¶m2, ¶m3, ¶m4 };
  150.     RETURN_TYPE retval;
  151.     if (_dispatch(msg, &retval, params, 4)) return retval;
  152.     return defval;
  153.   }
  154.  
  155.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
  156.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5) {
  157.     void *params[5] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5 };
  158.     RETURN_TYPE retval;
  159.     if (_dispatch(msg, &retval, params, 5)) return retval;
  160.     return defval;
  161.   }
  162.  
  163.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
  164.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6) {
  165.     void *params[6] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6 };
  166.     RETURN_TYPE retval;
  167.     if (_dispatch(msg, &retval, params, 6)) return retval;
  168.     return defval;
  169.   }
  170.  
  171.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
  172.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7) {
  173.     void *params[7] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6, ¶m7 };
  174.     RETURN_TYPE retval;
  175.     if (_dispatch(msg, &retval, params, 7)) return retval;
  176.     return defval;
  177.   }
  178.  
  179.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
  180.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8) {
  181.     void *params[8] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6, ¶m7, ¶m8 };
  182.     RETURN_TYPE retval;
  183.     if (_dispatch(msg, &retval, params, 8)) return retval;
  184.     return defval;
  185.   }
  186.  
  187.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
  188.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9) {
  189.     void *params[9] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6, ¶m7, ¶m8, ¶m9 };
  190.     RETURN_TYPE retval;
  191.     if (_dispatch(msg, &retval, params, 9)) return retval;
  192.     return defval;
  193.   }
  194.  
  195.   template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
  196.   RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10) {
  197.     void *params[10] = { ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6, ¶m7, ¶m8, ¶m9, ¶m10 };
  198.     RETURN_TYPE retval;
  199.     if (_dispatch(msg, &retval, params, 10)) return retval;
  200.     return defval;
  201.   }
  202.  
  203.   template <class CLASSNAME, class RETVAL>
  204.   void cb(RETVAL (CLASSNAME::*fn)(), void *retval, void **params, int nparam) {
  205.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)();
  206.   }
  207.  
  208.   template <class CLASSNAME>
  209.   void vcb(void (CLASSNAME::*fn)(), void *retval, void **params, int nparam) {
  210.     (static_cast<CLASSNAME *>(this)->*fn)();
  211.   }
  212.  
  213.   template <class CLASSNAME, class RETVAL, class PARAM1>
  214.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1), void *retval, void **params, int nparam) {
  215.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  216.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1);
  217.   }
  218.  
  219.   template <class CLASSNAME, class PARAM1>
  220.   void vcb(void (CLASSNAME::*fn)(PARAM1), void *retval, void **params, int nparam) {
  221.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  222.     (static_cast<CLASSNAME *>(this)->*fn)(*p1);
  223.   }
  224.  
  225.   template <class CLASSNAME, class PARAM1, class PARAM2>
  226.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2), void *retval, void **params, int nparam) {
  227.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  228.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  229.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2);
  230.   }
  231.  
  232.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2>
  233.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2), void *retval, void **params, int nparam) {
  234.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  235.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  236.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2);
  237.   }
  238.  
  239.   // 3 params
  240.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3>
  241.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3), void *retval, void **params, int nparam) {
  242.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  243.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  244.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  245.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3);
  246.   }
  247.  
  248.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3>
  249.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3), void *retval, void **params, int nparam) {
  250.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  251.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  252.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  253.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3);
  254.   }
  255.  
  256.   // 4 params
  257.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4>
  258.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4), void *retval, void **params, int nparam) {
  259.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  260.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  261.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  262.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  263.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4);
  264.   }
  265.  
  266.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4>
  267.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4), void *retval, void **params, int nparam) {
  268.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  269.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  270.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  271.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  272.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4);
  273.   }
  274.  
  275.   // 5 params
  276.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
  277.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5), void *retval, void **params, int nparam) {
  278.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  279.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  280.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  281.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  282.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  283.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5);
  284.   }
  285.  
  286.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
  287.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5), void *retval, void **params, int nparam) {
  288.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  289.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  290.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  291.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  292.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  293.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5);
  294.   }
  295.  
  296.   // 6 params
  297.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
  298.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6), void *retval, void **params, int nparam) {
  299.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  300.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  301.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  302.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  303.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  304. //    PARAM6 *p6 = static_cast<PARAM5*>(params[5]); // hey look, mig found a bug.
  305.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  306.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6);
  307.   }
  308.  
  309.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
  310.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6), void *retval, void **params, int nparam) {
  311.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  312.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  313.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  314.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  315.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  316. //    PARAM6 *p6 = static_cast<PARAM5*>(params[5]); // hey look, mig found a bug.
  317.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  318.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6);
  319.   }
  320.  
  321.   // 7 params
  322.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
  323.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7), void *retval, void **params, int nparam) {
  324.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  325.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  326.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  327.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  328.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  329.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  330.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  331.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7);
  332.   }
  333.  
  334.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
  335.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7), void *retval, void **params, int nparam) {
  336.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  337.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  338.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  339.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  340.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  341.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  342.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  343.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7);
  344.   }
  345.  
  346.   // 8 params
  347.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
  348.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8), void *retval, void **params, int nparam) {
  349.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  350.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  351.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  352.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  353.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  354.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  355.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  356.     PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
  357.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8);
  358.   }
  359.  
  360.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
  361.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8), void *retval, void **params, int nparam) {
  362.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  363.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  364.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  365.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  366.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  367.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  368.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  369.     PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
  370.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8);
  371.   }
  372.  
  373.   // 9 params
  374.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
  375.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9), void *retval, void **params, int nparam) {
  376.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  377.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  378.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  379.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  380.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  381.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  382.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  383.     PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
  384.     PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
  385.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9);
  386.   }
  387.  
  388.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
  389.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9), void *retval, void **params, int nparam) {
  390.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  391.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  392.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  393.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  394.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  395.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  396.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  397.     PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
  398.     PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
  399.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9);
  400.   }
  401.  
  402.   // 10 params
  403.   template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
  404.   void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10), void *retval, void **params, int nparam) {
  405.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  406.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  407.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  408.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  409.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  410.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  411.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  412.     PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
  413.     PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
  414.     PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
  415.     (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10);
  416.   }
  417.  
  418.   template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
  419.   void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10), void *retval, void **params, int nparam) {
  420.     PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
  421.     PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
  422.     PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
  423.     PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
  424.     PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
  425.     PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
  426.     PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
  427.     PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
  428.     PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
  429.     PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
  430.     *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10);
  431.   }
  432.  
  433.   enum { DESTRUCT=0xffff };
  434. };
  435. #define CB(x, y) case (x): cb(&CBCLASS::y, retval, params, nparam); break;
  436. #define VCB(x, y) case (x): vcb(&CBCLASS::y, retval, params, nparam); break;
  437.  
  438. #define RECVS_DISPATCH virtual int _dispatch(int msg, void *retval, void **params=NULL, int nparam=0)
  439.  
  440. #define START_DISPATCH \
  441.   int CBCLASS::_dispatch(int msg, void *retval, void **params, int nparam) { \
  442.     switch (msg) {
  443. //FINISH      case DESTRUCT: delete this; return 1;
  444. #define END_DISPATCH \
  445.       default: return 0; \
  446.     } \
  447.     return 1; \
  448.   }
  449. #define FORWARD_DISPATCH(x) \
  450.       default: return x::_dispatch(msg, retval, params, nparam); \
  451.     } \
  452.     return 1; \
  453.   }
  454.  
  455.  
  456. #if 0//CUT
  457. // stupid VC++ needs this sometimes... :(
  458. template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3>
  459. RETURN_TYPE _extcall(Dispatchable *dp, int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3) {
  460.   void *params[3] = { ¶m1, ¶m2, ¶m3 };
  461.   RETURN_TYPE retval;
  462.   if (dp->_dispatch(msg, &retval, params, 3)) return retval;
  463.   return defval;
  464. }
  465.  
  466. // helper classes to implement server-side methods
  467. class DispatchableCallback {
  468. protected:
  469.   DispatchableCallback(int _msgid) : msgid(_msgid) {}
  470. public:
  471.   virtual ~DispatchableCallback() {}
  472.  
  473.   int getMsgId() const { return msgid; }
  474.   virtual void _callback(void *obj, void *retval, void **param, int nparam)=0;
  475.  
  476. protected:
  477.   int msgid;
  478. };
  479.  
  480. // no params
  481. template<class CLASSNAME, class RETVAL>
  482. class callback0 : public DispatchableCallback {
  483. public:
  484.   typedef RETVAL (CLASSNAME::*fnPtrType)();
  485.   callback0(int msgid, fnPtrType _fnptr) :
  486.     DispatchableCallback(msgid),
  487.     fnptr(_fnptr) {}
  488.   virtual void _callback(void *obj, void *retval, void **param, int nparam) {
  489.     CLASSNAME *objptr = static_cast<CLASSNAME *>(obj);
  490.     RETVAL *ret = static_cast<RETVAL *>(retval);
  491.     *ret = (objptr->*fnptr)();
  492.   }
  493. private:
  494.   fnPtrType fnptr;
  495. };
  496.  
  497. // 1 param
  498. template<class CLASSNAME, class RETVAL, class PARAM1>    // exp
  499. class callback1 : public DispatchableCallback {
  500. public:
  501.   typedef RETVAL (CLASSNAME::*fnPtrType)(PARAM1);    // exp
  502.   callback1(int msgid, fnPtrType _fnptr) :
  503.     DispatchableCallback(msgid),
  504.     fnptr(_fnptr) {}
  505.   virtual void _callback(void *obj, void *retval, void **param, int nparam) {
  506.     CLASSNAME *objptr = static_cast<CLASSNAME *>(obj);
  507.     RETVAL *ret = static_cast<RETVAL *>(retval);
  508.     PARAM1 *p1 = static_cast<PARAM1*>(param[0]);    // exp
  509.     *ret = (objptr->*fnptr)(*p1);            // exp
  510.   }
  511. private:
  512.   fnPtrType fnptr;
  513. };
  514.  
  515. // 2 params
  516. template<class CLASSNAME, class RETVAL, class PARAM1, class PARAM2>    // exp
  517. class callback2 : public DispatchableCallback {
  518. public:
  519.   typedef RETVAL (CLASSNAME::*fnPtrType)(PARAM1, PARAM2);    // exp
  520.   callback2(int msgid, fnPtrType _fnptr) :
  521.     DispatchableCallback(msgid),
  522.     fnptr(_fnptr) {}
  523.   virtual void _callback(void *obj, void *retval, void **param, int nparam) {
  524.     CLASSNAME *objptr = static_cast<CLASSNAME *>(obj);
  525.     RETVAL *ret = static_cast<RETVAL *>(retval);
  526.     PARAM1 *p1 = static_cast<PARAM1*>(param[0]);    // exp
  527.     PARAM2 *p2 = static_cast<PARAM2*>(param[1]);    // exp
  528.     *ret = (objptr->*fnptr)(*p1, *p2);            // exp
  529.   }
  530. private:
  531.   fnPtrType fnptr;
  532. };
  533.  
  534. // 2 params, no return val
  535. template<class CLASSNAME, class PARAM1, class PARAM2>    // exp
  536. class voidcallback2 : public DispatchableCallback {
  537. public:
  538.   typedef void (CLASSNAME::*fnPtrType)(PARAM1, PARAM2);    // exp
  539.   voidcallback2(int msgid, fnPtrType _fnptr) :
  540.     DispatchableCallback(msgid),
  541.     fnptr(_fnptr) {}
  542.   virtual void _callback(void *obj, void *retval, void **param, int nparam) {
  543.     CLASSNAME *objptr = static_cast<CLASSNAME *>(obj);
  544.     PARAM1 *p1 = static_cast<PARAM1*>(param[0]);    // exp
  545.     PARAM2 *p2 = static_cast<PARAM2*>(param[1]);    // exp
  546.     (objptr->*fnptr)(*p1, *p2);            // exp
  547.   }
  548. private:
  549.   fnPtrType fnptr;
  550. };
  551.  
  552. // 3 params
  553. template<class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3>    // exp
  554. class callback3 : public DispatchableCallback {
  555. public:
  556.   typedef RETVAL (CLASSNAME::*fnPtrType)(PARAM1, PARAM2, PARAM3);    // exp
  557.   callback3(int msgid, fnPtrType _fnptr) :
  558.     DispatchableCallback(msgid),
  559.     fnptr(_fnptr) {}
  560.   virtual void _callback(void *obj, void *retval, void **param, int nparam) {
  561.     CLASSNAME *objptr = static_cast<CLASSNAME *>(obj);
  562.     RETVAL *ret = static_cast<RETVAL *>(retval);
  563.     PARAM1 *p1 = static_cast<PARAM1*>(param[0]);    // exp
  564.     PARAM2 *p2 = static_cast<PARAM2*>(param[1]);    // exp
  565.     PARAM3 *p3 = static_cast<PARAM3*>(param[2]);    // exp
  566.     *ret = (objptr->*fnptr)(*p1, *p2, *p3);        // exp
  567.   }
  568. private:
  569.   fnPtrType fnptr;
  570. };
  571.  
  572. // 4 params
  573. template<class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4>    // exp
  574. class callback4 : public DispatchableCallback {
  575. public:
  576.   typedef RETVAL (CLASSNAME::*fnPtrType)(PARAM1, PARAM2, PARAM3, PARAM4);    // exp
  577.   callback4(int msgid, fnPtrType _fnptr) :
  578.     DispatchableCallback(msgid),
  579.     fnptr(_fnptr) {}
  580.   virtual void _callback(void *obj, void *retval, void **param, int nparam) {
  581.     CLASSNAME *objptr = static_cast<CLASSNAME *>(obj);
  582.     RETVAL *ret = static_cast<RETVAL *>(retval);
  583.     PARAM1 *p1 = static_cast<PARAM1*>(param[0]);    // exp
  584.     PARAM2 *p2 = static_cast<PARAM2*>(param[1]);    // exp
  585.     PARAM3 *p3 = static_cast<PARAM3*>(param[2]);    // exp
  586.     PARAM4 *p4 = static_cast<PARAM4*>(param[3]);    // exp
  587.     *ret = (objptr->*fnptr)(*p1, *p2, *p3, *p4);        // exp
  588.   }
  589. private:
  590.   fnPtrType fnptr;
  591. };
  592.  
  593. inline int Dispatchable::_dispatch(int msg, void *retval, void **params, int nparam) {
  594.   DispatchableCallback **dlist = dispatchable_getCallbackList();
  595.   for (int i = 0; ; i++) {
  596.     DispatchableCallback *rec = dlist[i];
  597.     if (rec == NULL) break;
  598.     if (rec->getMsgId() == msg) {
  599.       rec->_callback(this, retval, params, nparam);
  600.       return 1;
  601.     }
  602.   }
  603.   return 0;
  604. }
  605. #endif
  606.  
  607.  
  608. #endif
  609.